#pragma once
#include "Protocol.hpp"
#include "Socket.hpp"
#include <pthread.h>
#include <functional>

using namespace std;

using func_t = function<string(string &inbufferstream, bool* error_code)>; //&是必须的

class TcpServer;
class ThreadData
{
public:
    ThreadData(TcpServer *tcp_this, Network::Socket *sockp)
        : _tcp_this(tcp_this), _sockp(sockp)
    {
    }

public:
    TcpServer *_tcp_this;
    Network::Socket *_sockp;
};

class TcpServer
{
public:
    TcpServer(uint16_t port, func_t handler_request)
        : _port(port), _listensocket(new Network::TcpSocket()), _handler_request(handler_request)
    {
        _listensocket->BuildlistenSocketMethod(_port, Network::backlog);
    }
    static void *Threadrun(void *args)
    {
        pthread_detach(pthread_self()); // 分离线程
        ThreadData *td = static_cast<ThreadData *>(args);

        string inbufferstream;
        while (true)
        {
            bool ok = true;
            // 1.读取报文
            if (!td->_sockp->Recv(&inbufferstream, 1024))
                break;
            // 读取数据——不关心数据是什么，只读取
            // 2.报文处理
            string send_string = td->_tcp_this->_handler_request(inbufferstream, &ok); // 回掉不仅仅是掉出去了，还会回来
            if (ok)
            {
                if (!send_string.empty())
                {
                    // 发送数据——不关心数据是什么，只发送
                    // 3.发送数据
                    td->_sockp->Send(send_string);
                }
            }
            else
            {
                break;
            }
        }

        td->_sockp->CloseSocket();
        delete td->_sockp;
        delete td;

        return nullptr;
    }
    void Loop()
    {
        while (true)
        {
            string peerip;
            uint16_t peerport;
            Network::Socket *newsock = _listensocket->AcceptConnection(&peerip, &peerport);
            cout << "获取一个新连接,sockfd:" << newsock->GetSockfd() << "client info:" << peerip << ":" << peerport << endl;

            pthread_t tid;
            ThreadData *td = new ThreadData(this, newsock);
            pthread_create(&tid, nullptr, Threadrun, td);
        }
    }
    ~TcpServer()
    {
        delete _listensocket;
    }

private:
    int _port;
    Network::Socket *_listensocket;

public:
    func_t _handler_request;
};